# -*- coding = utf-8 -*-
# @Time：2022/3/11 20:01
# @Author：3ic
# @File：executor.py.py
# @Software：PyCharm

import time
from multiprocessing import Process

import numpy as np
import win32con
import win32gui

from iclogger import IcLogger
from window_options import fastCapture, winPressKey, winClickMouse, cap_hwnd, screen, opt_hwnd


class Executor(Process):
    _logger = IcLogger('logs/executor.logs')

    def __init__(self, time_point_pipe, auto_break: bool, no_speedup_ub: bool, speedup_mode: int):
        Process.__init__(self)
        self._time_point_pipe = time_point_pipe
        self._auto_brake = auto_break
        self._no_speedup_ub = no_speedup_ub
        self._speedup_mold = speedup_mode
        self._is_working = True

    def _setSpeed(self, target_state=0):
        vote = np.zeros(3)
        while True:
            vote[:] = 0
            for i in range(20):
                vote[(np.sum(fastCapture(screen, cap_hwnd, 1703, 945, 14, 5)[:, :, 2] > 176) // 27 + 1) % 3] += 1
                time.sleep(0.01)
            max_idx = np.argmax(vote)
            if target_state == max_idx:
                break
            winPressKey(opt_hwnd, 'X',
                        (target_state - max_idx + self._speedup_mold) % self._speedup_mold, 0.15)
            time.sleep(0.1)

    def _executeTimePoint(self, time_point):
        if time_point[2] == 7:
            self._setSpeed((self._speedup_mold - 1 + time_point[3]*(self._speedup_mold - 1)) >> 1)
            return

        idx = 2
        while time_point[idx] != '#':
            key, press_cnt, wait_t = (time_point[idx], time_point[idx + 1], time_point[idx + 2])
            if key == 6:
                winPressKey(opt_hwnd, 'Z')
            else:
                win32gui.SendMessage(opt_hwnd, win32con.WM_KEYDOWN, 48 + key, 0)
                pox_x = 330 + 221 * key  # 356
                isReady = np.sum(fastCapture(screen, cap_hwnd, pox_x, 990, 1, 14)[:, :, 0] > 100) > 3
                if isReady:
                    pox_x -= 30
                for i in range(press_cnt):
                    if np.sum(fastCapture(screen, cap_hwnd, pox_x, 990, 1, 14)[:, :, 0] > 100) > 3:
                        if not isReady:
                            pox_x -= 30
                            isReady = True
                    elif isReady:
                        break
                    time.sleep(0.005)
                win32gui.SendMessage(opt_hwnd, win32con.WM_KEYUP, 48 + key, 0)
            if self._no_speedup_ub:
                time.sleep(wait_t)
            elif wait_t > 2:
                self._setSpeed(1)
                time.sleep((wait_t - 0.8) / 4)
                self._setSpeed(0)
            idx += 3

    def run(self):
        Executor._logger.info('\n\n=== executor开始工作 ===')
        try:
            # 执行打轴命令
            time_point = self._time_point_pipe.recv()
            while time_point[0] > 0:
                self._executeTimePoint(time_point)
                time_point = self._time_point_pipe.recv()
                Executor._logger.info('执行操作' + str(time_point[0]))
            self._is_working = False  # 正常结束工作
        except BaseException as e:
            Executor._logger.warning(e)

    def doStarting(self):
        time.sleep(0.2)
        winClickMouse(opt_hwnd, 1600, 870)

    def doBraking(self):
        for i in range(1, 6):
            win32gui.SendMessage(opt_hwnd, win32con.WM_KEYUP, 48 + i, 0)
            time.sleep(0.01)
        if self._is_working or self._auto_brake:
            winClickMouse(opt_hwnd, 1713, 82)
        self._is_working = False  # 过程中结束工作

